package org.senf.outerspace.ships.ui;

import java.util.List;

import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.part.ViewPart;
import org.senf.outerspace.ships.BluePrintFactory;
import org.senf.outerspace.ships.build.Ship;
import org.senf.outerspace.ships.design.IEngineBluePrint;
import org.senf.outerspace.ships.design.IModelBluePrint;
import org.senf.outerspace.ships.design.IWeaponBluePrint;
import org.senf.outerspace.ships.design.ShipBluePrint;
import org.senf.outerspace.ships.event.ShipEvent;
import org.senf.outerspace.ships.event.ShipEventListener;
import org.senf.outerspace.ships.event.ShipEventManager;
import org.senf.outerspace.ships.event.ShipEventProvider;

public class ShipDesignView extends ViewPart implements ShipEventProvider {
	
	public final static String ID = "org.senf.outerspace.ships.ui.ShipDesignView";

	private Composite container;
	private Combo modelCombo;
	private Combo engineCombo;
	private Combo weaponCombo;
	private Button createBtn;
	
	private ShipEventManager shipEventManager;
	
	public ShipDesignView() {
		shipEventManager = new ShipEventManager();
	}
	
	@Override
	public void createPartControl(Composite parent) {
		parent.setLayout(new FillLayout());
		
		container = new Composite(parent, SWT.NONE);
		GridLayoutFactory.fillDefaults().margins(5,5).numColumns(2).applyTo(container);
		
		Label lbl = new Label(container, SWT.NONE);
		lbl.setText("Model:");
		modelCombo = new Combo(container, SWT.READ_ONLY);
		GridDataFactory.fillDefaults().grab(true,false).applyTo(modelCombo);
		
		lbl = new Label(container, SWT.NONE);
		lbl.setText("Engine:");
		engineCombo = new Combo(container, SWT.READ_ONLY);
		GridDataFactory.fillDefaults().grab(true,false).applyTo(engineCombo);
		
		lbl = new Label(container, SWT.NONE);
		lbl.setText("Weapon:");
		weaponCombo = new Combo(container, SWT.READ_ONLY);
		GridDataFactory.fillDefaults().grab(true,false).applyTo(weaponCombo);
		
		createBtn = new Button(container, SWT.PUSH);
		createBtn.setText("Create");
		createBtn.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				createBluePrint();
			}
		});
		initData();
	}

	@Override
	public void setFocus() {
		modelCombo.setFocus();
	}
	
	/*
	 * ******************
	 * Non-public helpers
	 * ******************
	 */
	
	private void initData() {
		List<IModelBluePrint> models = BluePrintFactory.getInstance().getAvailableModels();
		String[] names = new String[models.size()];
		for (int i=0; i<models.size(); i++) {
			names[i] = models.get(i).getName();
		}
		modelCombo.setItems(names);
		modelCombo.select(0);
		modelCombo.setData(models);

		List<IEngineBluePrint> engines = BluePrintFactory.getInstance().getAvailableEngines();
		names = new String[engines.size()];
		for (int i=0; i<engines.size(); i++) {
			names[i] = engines.get(i).getName();
		}
		engineCombo.setItems(names);
		engineCombo.select(0);
		engineCombo.setData(engines);
		
		List<IWeaponBluePrint> weapons = BluePrintFactory.getInstance().getAvailableWeapons();
		names = new String[weapons.size()];
		for (int i=0; i<weapons.size(); i++) {
			names[i] = weapons.get(i).getName();
		}
		weaponCombo.setItems(names);
		weaponCombo.select(0);
		weaponCombo.setData(weapons);
	}
	
	@SuppressWarnings("unchecked")
	private void createBluePrint() {
		int index = modelCombo.getSelectionIndex();
		List<IModelBluePrint> models = (List<IModelBluePrint>)modelCombo.getData();
		IModelBluePrint modelBp = models.get(index);
		
		index = engineCombo.getSelectionIndex();
		List<IEngineBluePrint> engines = (List<IEngineBluePrint>)engineCombo.getData();
		IEngineBluePrint engineBp = engines.get(index);
		
		index = weaponCombo.getSelectionIndex();
		List<IWeaponBluePrint> weapons = (List<IWeaponBluePrint>)weaponCombo.getData();
		IWeaponBluePrint weaponBp = weapons.get(index);
		
		ShipBluePrint bp = new ShipBluePrint();
		bp.setModelBluePrint(modelBp);
		bp.setEngineBluePrint(engineBp);
		bp.setWeaponBluePrint(weaponBp);
			
		ShipEvent e = new ShipEvent();
		e.type = ShipEvent.TYPE_DESIGN_CREATED;
		e.data = bp;
		fire(e);
		
		Ship ship = bp.build();
		
		e = new ShipEvent();
		e.type = ShipEvent.TYPE_SHIP_CREATED;
		e.data = ship;
		fire(e);
	}
	
	/*
	 * ***********
	 * Ship Events
	 * ***********
	 */
	
	public void addListener(ShipEventListener listener) {
		shipEventManager.addListener(listener);
	}
	
	public void removeListener(ShipEventListener listener) {
		shipEventManager.removeListener(listener);
	}
	
	private void fire(ShipEvent e) {
		shipEventManager.fire(e);
	}
}
